package main

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/ClickHouse/clickhouse-go/v2"
	"time"
)

func OpenDB() (conn *sql.DB) {
	conn = clickhouse.OpenDB(&clickhouse.Options{
		Addr: []string{"132.126.3.231:8123"},
		Auth: clickhouse.Auth{
			Database: "default",
			Username: "default",
			Password: "Eshore@135",
		},
		Settings: clickhouse.Settings{
			"max_execution_time": 60,
		},
		DialTimeout: 30 * time.Second,
		Compression: &clickhouse.Compression{
			Method: clickhouse.CompressionLZ4,
		},
		Protocol: clickhouse.HTTP,
	})
	conn.SetMaxIdleConns(5)
	conn.SetMaxOpenConns(10)
	conn.SetConnMaxLifetime(time.Hour)

	return conn
}

func CreateTable(conn *sql.DB) {
	const ddl = `
		CREATE TABLE IF NOT EXISTS example (
			  Col1 UInt64
			, Col2 String
			, Col3 Array(UInt8)
			, Col4 DateTime
		) ENGINE = Memory
	`
	_, err := conn.Exec(ddl)
	if err != nil {
		fmt.Println("创建表异常！")
		fmt.Println(err)
	} else {
		fmt.Println("创建表成功！")
	}
}

func InsertRows(conn *sql.DB) {
	ctx := clickhouse.Context(context.Background(), clickhouse.WithStdAsync(false))
	{
		for i := 0; i < 100; i++ {
			_, err := conn.ExecContext(ctx, `INSERT INTO example VALUES (
				?, ?, ?, now()
			)`, i, "Golang SQL database driver", []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9})
			if err != nil {
				fmt.Println("插入数据异常！")
				fmt.Println(err)
			} else {
				fmt.Println("插入数据成功！")
			}
		}
	}
}

func QueryRows(conn *sql.DB) {
	row := conn.QueryRow("SELECT Col1 , Col2, Col3 FROM example LIMIT 10 OFFSET 0")
	var (
		col1 uint64
		col2 string
		col3 []uint8
	)
	if err := row.Scan(&col1, &col2, &col3); err != nil {
		fmt.Println("查询数据异常！")
		fmt.Println(err)
	} else {
		fmt.Println("查询数据成功！")
	}
	fmt.Printf("row: col1=%d, col2=%s, col3=%s\n", col1, col2, col3)
}

func CloseDB(conn *sql.DB) {
	defer func() {
		err := conn.Close()
		if err != nil {
			fmt.Println("关闭连接异常！")
			fmt.Println(err)
			return
		} else {
			fmt.Println("关闭连接成功！")
		}
	}()
}
